package notwork;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UdpEchoSever_3 {
     DatagramSocket socket=null;
//给服务器搞一个"电话",让他可以使用这个电话来接收和发送信息
    public UdpEchoSever_3(int port) throws SocketException {
       socket=new DatagramSocket(port);
       //指定一个端口让服务器来使用
    }

    public void start() throws IOException {
        //打印个信息，表示服务器启动
        System.out.println("服务器启动");

        /**
         * 循环一次代表处理一次请求，也就是对方发个问题过来，你给他解决，
         *
         * 然而处理请求的过程一般分为三步
         * 1.读取请求并解析
         * 2.根据请求，计算响应（服务器最为关键的一步）
         * 3.把响应返回给客户端
         **/

        while(true){
            //1.读取请求并解析
            //   DatagramPacket 表示一个数据报，此处传入的字节数组，就保存UDP的载荷部分。
            DatagramPacket requestPacket=new DatagramPacket(new byte[40960],40960);
           //接收客户端发来的数据报
            socket.receive(requestPacket);
            //把读取到的二进制数据，转换成字符串，只是构造有效的部分
            String request=new String(requestPacket.getData(),0, requestPacket.getLength());

            //2.根据请求，计算响应
            //我们此处写的是回显服务器
            //所以意思意思，写个计算响应的方法，将请求原封不动的返回一下
            String reponse=process(request);

            //3.把响应返回给客户端
            //将字符串转化为字节数组，然后获取字节数组的长度，并使用接收的数据报获取客户端的IP地址和端口号
            DatagramPacket reponsePacket=new DatagramPacket(reponse.getBytes(),reponse.getBytes().length, requestPacket.getSocketAddress());
           //将响应的数据报发送给客户端
            socket.send(reponsePacket);
            //打印一下日志
            System.out.printf("[%s:%d]  rqs:%s   rep:%s",requestPacket.getAddress(),requestPacket.getPort(),request,reponse);
        }

    }


    //后续写其他服务器时，只需要修改一下计算响应的这个方法就行了
    //可以继承这个类，然后重写process方法，将private修改为public就行
    public String process(String request) {
    return request;
    }

    public static void main(String[] args) throws IOException {
     UdpEchoSever_3 sever_3=new UdpEchoSever_3(4565);
        sever_3.start();
    }
}
